package src;

import java.util.logging.Level;
import java.util.logging.Logger;
import src.HttpdConf;
import java.io.*;
import java.util.*;
import java.net.*;
import java.io.File.*;
import src.Request;


/**
 * <p>Title: WebServer.java</p>
 *
 * <p>Description: This is the main class of the server. This is where
 * everything is instantiated and configured. Here is also where multithreading
 * of the server will occur.</p>
 *
 * <p>Copyright: Copyright (c) 2005</p>
 *
 * <p>Company: </p>
 * @author Tracie Hong and Luping May
 * @version 1.0
 */
public class WebServer {
 int numberOfThreads=0;
  /**
   * Here you will create your server, configure all the settings and listen to
   * the port designated within your configuration. Whenever a request comes in,
   * you will need to process that request appropriately and respond as needed.
   *
   * @param args String[]
   */


  public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException {
    //Set up and test httpd.conf
      //int activeThreads=0;
    int maxThreads=10;
    HttpdConf conf = new HttpdConf();
    String file = File.separator + "home" + File.separator + "sean" + File.separator
            + "School" + File.separator + "CSC667" + File.separator + "MyWebserver"
            + File.separator + "conf" + File.separator;
    /*conf.readHttpd(File.separator + "home" + File.separator + "sean" + File.separator
            + "School" + File.separator + "CSC667" + File.separator + "Web Server" + File.separator);
     */

    conf.readHttpd(file);
    System.out.println(conf.getFromConf("Listen"));
    Mimes mimeTable = new Mimes();
    mimeTable.readMimeFile(file);

    //Attempting socket connection
    ServerSocket sox = new ServerSocket(Integer.parseInt(conf.getFromConf("Listen")), 0, InetAddress.getByName(null));

    while( true )
    {
    System.out.println("Waiting for connection");
    Socket connection = new Socket();
    connection = sox.accept();

    //keep number of threads counted
    clientThread  thread = new clientThread(connection, conf, mimeTable); ;
    while (thread.getThreadGroup().activeCount() >= maxThreads){
       // wait();
    }
     System.out.println("Connection received from " + connection.getInetAddress().getHostName());
     thread.run();
    }//end while
  }//end main
}//end class

  /**
   * Private class used for multithreading
   */
  class clientThread extends Thread {
      Socket soc;
      HttpdConf hpdc;
      Mimes m;
    /**
     * Constructor used to start a thread.
     *
     * @param incoming Socket value which designates the socket used by the client
     * @param hcf HttpdConf object created upon server startup.
     */
    public clientThread(Socket incoming, HttpdConf hcf, Mimes mime) throws IOException {
        soc = incoming;
        hpdc = hcf;
        m=mime;
    }

    /**
     * Used to run your server thread. Here is where you will be processing all
     * requests and returning your responses.
     */
    public void run() {

        try {

            OutputStream out = soc.getOutputStream();

            //Look for and setup request
            //System.out.println("Waiting for request: ");
            Request req = new Request();
            BufferedReader reqFile = new BufferedReader(new InputStreamReader(soc.getInputStream()) );
            //BufferedReader reqSocket = new BufferedReader(new InputStreamReader(soc.getInputStream()));
            //while(req.equals(null)) req.wait();
            req.parse(reqFile);     //Parse request from i=file
            Environment env = new Environment(hpdc, req, new Socket());
            //Test print headers
            System.out.println(req.getURI());
            System.out.println("\n Printing Headers:");
            ArrayList<String> headers = new ArrayList<String>();
            headers = req.getHeaders();
            for( int i = 0; i < headers.size(); i++ )
                System.out.println(headers.get(i));
            //System.out.println(req.getHeaders());
            //Write Output from Response
            Response res = new Response();
            res.processRequest(req, m.getMimes(), env);
            out = soc.getOutputStream();
            //out.flush();
            res.writeOutput(out);
            out.flush();
            soc.close();
            out.close();
        } catch (IOException ex) {
                System.out.println("IOException caught. damn");
        }
        }//end ruhn
  }//end client

